package judesart.app.client.gallery.ui;

import java.util.List;

import judesart.app.client.gallery.GalleryController;
import judesart.app.client.gallery.GalleryControllerAsync;
import judesart.app.client.widget.TopInfo;
import judesart.app.domain.Gallery;
import judesart.app.domain.Room;
import judesart.app.shared.SearchResult;

import com.allen_sauer.gwt.log.client.Log;
import com.extjs.gxt.ui.client.Style.HorizontalAlignment;
import com.extjs.gxt.ui.client.data.BaseListLoader;
import com.extjs.gxt.ui.client.data.BeanModel;
import com.extjs.gxt.ui.client.data.BeanModelReader;
import com.extjs.gxt.ui.client.data.ListLoadResult;
import com.extjs.gxt.ui.client.data.ListLoader;
import com.extjs.gxt.ui.client.data.RpcProxy;
import com.extjs.gxt.ui.client.event.ButtonEvent;
import com.extjs.gxt.ui.client.event.Events;
import com.extjs.gxt.ui.client.event.Listener;
import com.extjs.gxt.ui.client.event.SelectionChangedEvent;
import com.extjs.gxt.ui.client.event.SelectionListener;
import com.extjs.gxt.ui.client.store.ListStore;
import com.extjs.gxt.ui.client.widget.Composite;
import com.extjs.gxt.ui.client.widget.ContentPanel;
import com.extjs.gxt.ui.client.widget.ListView;
import com.extjs.gxt.ui.client.widget.button.Button;
import com.google.gwt.user.client.Timer;
import com.google.gwt.user.client.rpc.AsyncCallback;

public class GalleriesPanel extends Composite
{
    GalleryControllerAsync service = GalleryController.Util.getInstance();
    private final ContentPanel listPanel;
    private final GalleryDetailsPanel detailsPanel;

    public GalleriesPanel()
    {
        this(null, null);
    }

    public GalleriesPanel(Long galleryId)
    {
        this(galleryId, null);
    }

    public GalleriesPanel(String roomKey)
    {
        this(null, roomKey);
    }

    private GalleriesPanel(Long galleryId, String roomKey)
    {
        final ContentPanel mainPanel = new ContentPanel();
        mainPanel.setHeaderVisible(false);
        mainPanel.setFrame(false);
        mainPanel.setBorders(false);

        RpcProxy<List<Gallery>> proxy = new RpcProxy<List<Gallery>>()
        {
            @Override
            protected void load(Object loadConfig,
                    final AsyncCallback<List<Gallery>> callback)
            {
                Log.debug(" > Load galleries");
                getGalleries(callback);
            }
        };

        ListLoader<ListLoadResult<Gallery>> loader = new BaseListLoader<ListLoadResult<Gallery>>(
                proxy, new BeanModelReader());
        ListStore<BeanModel> store = new ListStore<BeanModel>(loader);
        loader.load();

        listPanel = new ContentPanel();
        listPanel.setCollapsible(false);
        listPanel.setAnimCollapse(false);
        listPanel.setFrame(true);
        listPanel.setId("galleries-view");
        listPanel.setHeading("Galleries");
        listPanel.setWidth(800);
        listPanel.setHeight(513);
        listPanel.setBodyBorder(false);

        ListView<BeanModel> view = new ListView<BeanModel>()
        {
            @Override
            protected BeanModel prepareData(BeanModel model)
            {
                Gallery g = model.getBean();
                if (g.getRooms() != null && g.getRooms().size() > 0)
                {
                    for (Room room : g.getRooms())
                    {
                        if (room.getArtworks() != null
                                && room.getArtworks().size() > 0)
                        {
                            model.set(
                                    "photoId",
                                    room.getArtworks().get(0).getMainImageId().toString());
                            break;
                        }
                    }
                }
                return model;
            }
        };

        view.setTemplate(getTemplate());
        view.setStore(store);
        view.setItemSelector("div.thumb-wrap");
        view.getSelectionModel().addListener(Events.SelectionChange,
                new Listener<SelectionChangedEvent<BeanModel>>()
                {

                    public void handleEvent(SelectionChangedEvent<BeanModel> be)
                    {
                        Log.debug(" handleEvent Selection ["
                                + be.getSelection().size() + "]");
                        if (be.getSelection().size() > 0)
                        {
                            Log.debug(" handleEvent 0 ["
                                    + be.getSelection().get(0).get("id") + "]");
                            open((Long) be.getSelection().get(0).get("id"));
                        }
                    }

                });
        view.setBorders(false);
        view.setHeight(430);
        listPanel.add(view);

        Button btnAddNew = new Button("Add New");
        btnAddNew.addSelectionListener(new SelectionListener<ButtonEvent>()
        {
            @Override
            public void componentSelected(ButtonEvent ce)
            {
                open(null);
            }
        });
        listPanel.addButton(btnAddNew);
        listPanel.setButtonAlign(HorizontalAlignment.RIGHT);
        mainPanel.add(listPanel);
        detailsPanel = new GalleryDetailsPanel();
        mainPanel.add(detailsPanel);
        initComponent(mainPanel);
        final Timer hideDetailsPanelTimer = new Timer()
        {
            @Override
            public void run()
            {
                detailsPanel.hide();
            }
        };
        if (galleryId == null && roomKey == null)
        {
            hideDetailsPanelTimer.schedule(200);
        } else
        {
            if (galleryId != null)
            {
                open(galleryId);
            } else
            {
                openRoom(roomKey);
            }
        }
    }

    public void open(Long galleryId)
    {
        Log.debug("open -> [" + galleryId + "]");
        listPanel.hide();
        detailsPanel.open(galleryId);
        detailsPanel.show();
    }

    public void openRoom(String roomKey)
    {
        listPanel.hide();
        service.getRoom(roomKey, new AsyncCallback<Room>()
        {
            @Override
            public void onFailure(Throwable caught)
            {
                Log.error("Unable to get room", caught);
                TopInfo.display("Error", "Unable to open room");
                detailsPanel.hide();
                listPanel.show();
            }

            @Override
            public void onSuccess(Room room)
            {
                detailsPanel.open(room.getGallery());
                detailsPanel.openRoom(room);
                detailsPanel.show();
            }
        });
    }

    private native String getTemplate() /*-{
        return ['<tpl for=".">', 
        '<div style="float: left; width: 140px;" class="thumb-wrap" id="{id}">', 
        '<div class="thumb"><img src="/image?id={photoId}&size=100x100&crop=true" title="{title}"/></div>', 
        '<div style="text-align: center; width: 100%;">{title}</div>', 
        '</div>',
        '</tpl>', 
        '<div class="x-clear"></div>'].join("");
    }-*/;

    private void getGalleries(final AsyncCallback<List<Gallery>> callback)
    {
        service.searchGalleries(0, 500,
                new AsyncCallback<SearchResult<Gallery>>()
                {
                    @Override
                    public void onFailure(Throwable caught)
                    {
                        callback.onFailure(caught);
                    }

                    public void onSuccess(SearchResult<Gallery> result)
                    {
                        callback.onSuccess(result.getResults());
                    };
                });
    }
}
